import hashlib
import os
import random
import shutil
import time
import jwt
import qrcode
import redis
import json
import requests
from datetime import datetime
from django.shortcuts import render, redirect
from dwebsocket.decorators import accept_websocket
from rest_framework.views import APIView
from rest_framework.response import Response
from z_FinanceApp.PyMongo import PyMongo
from z_FinanceApp.models import UserModel
from mydjango.settings import FILE_ROOT, mongo_db, mongo_port, mongo_jh
from django.http.response import JsonResponse, HttpResponse
from bs4 import BeautifulSoup
from .PyRedis import PyRedis


# 注册视图
class Register(APIView):
    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        try:
            user = UserModel(username=username, password=password)
            user.save()
            return Response({'code': 200, 'msg': '恭喜您，注册成功'})
        except Exception as e:
            print(str(e))
            return Response({'code': 405, 'msg': 'Sorry，用户已存在'})


# 分片上传
class FileUpload(APIView):
    def post(self, request):
        file_obj = request.data.get('file')
        file_name = request.data.get('name')
        f_name = request.data.get('f_name')

        path_lis = os.listdir(FILE_ROOT)
        # 创建切片接收目录
        if not f_name in path_lis:
            os.mkdir(FILE_ROOT + '\\{}'.format(f_name))

        filename = FILE_ROOT + '\\{}\\'.format(f_name) + file_name

        with open(filename, 'wb') as f:
            for line in file_obj:
                f.write(line)
        return JsonResponse({'msg': '上传成功'})

    def put(self, request):
        file_num = request.data.get('index')
        file_name = request.data.get('filename')

        files_seve_url = FILE_ROOT + '\\UploadFile\\' + file_name
        files_read_url = FILE_ROOT + '\\{}\\'.format(file_name)

        # 拼接文件
        with open(files_seve_url, 'ab') as f:
            for i in range(int(file_num)):
                url = files_read_url + file_name + str(i)

                with open(url, 'rb') as r:
                    line = r.read()
                    f.write(line)

        # 删除分片目录
        shutil.rmtree(files_read_url)

        return Response({'msg': '拼接完成'})


# 登录视图
class Login(APIView):
    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        user = UserModel.objects.filter(username=username, password=password).first()
        if user:
            return Response({"msg": "登录成功", 'uid': user.id, "code": 200})
        else:
            return Response({"msg": "登录失败", "code": 400})


# 在线人数
def visit(request):
    r = redis.Redis(decode_responses=True)
    if r.exists('myset'):
        r.sadd('myset', request.META['REMOTE_ADDR'])
    else:
        r.expire('myset', 300)
        r.sadd('myset', request.META['REMOTE_ADDR'])
    return JsonResponse({'msg': r.scard('myset')})


@accept_websocket
def LoginVisit(request):
    r = redis.Redis(decode_responses=True)
    if request.is_websocket():
        while True:
            if r.exists('myset'):
                r.sadd('myset', request.META['REMOTE_ADDR'])
            else:
                r.sadd('myset', request.META['REMOTE_ADDR'])
                r.expire('myset', 30)
            request.websocket.send(json.dumps({'len': r.scard('myset')}))
            time.sleep(1)


m = PyMongo(mongo_db, mongo_jh, **mongo_port)


class Echarts(APIView):

    def get(self, request):
        url = 'http://www.chinamoney.com.cn/ags/ms/cm-u-bk-ccpr/CcprHisNew?startDate=2021-03-07&endDate=2021-04-07&currency=USD/CNY&pageNum=1&pageSize=30'

        headers = {
            "User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'
        }

        c = json.loads(requests.get(url=url, headers=headers).text)['records']
        # for i in c:
        #     m.insert(i)

        return Response({})


# 输出汇率
class Echarts_Val(APIView):

    def get(self, request):
        list_data = []
        for i in m.find():
            _ = {}
            _['values'] = i['values']
            _['date'] = i['date']
            list_data.append(_)
        list_data = sorted(list_data, key=lambda x: x['date'])
        return Response(list_data)


class Echartsday(APIView):

    def get(self, request):
        url = 'https://qt.gtimg.cn/q=whXAUUSD,whXAGUSD,whEURUSD,whGBPUSD,whUSDCHF,whUSDCAD,whUSDJPY,whUSDHKD,whAUDUSD,whSGDUSD,whUSDSEK,whUSDCNY,whNZDUSD,whEURJPY,whCHFJPY,whNZDCHF,whNZDHKD,whNZDJPY,whAUDHKD,whAUDJPY,whXAUGBP,whEURHKD,whCASF,whAUDEUR,whERSF&r=666691024'

        headers = {
            "User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'
        }

        c = requests.get(url=url, headers=headers).text
        c = c.split(';')
        c = c[7]
        c = c.split('~')
        hl = c[3]  # 汇率
        da = c[5]
        y = da[0:4] + '-'
        m = da[4:6] + '-'
        d = da[6:8]
        day = y + m + d  # 年月日
        h = da[8:10] + ':'
        f = da[10:12] + ':'
        s = da[12:14]
        data = h + f + s  # 时分秒
        print(day, data)

        m = PyMongo(mongo_db, 'con', **mongo_port)
        m.insert({'hl': hl, 'day': day, 'time': data})

        return Response({})


@accept_websocket
def Echartsday_val(request):
    if request.is_websocket():
        while 1:
            m = PyMongo(mongo_db, 'con', **mongo_port)
            list_data = []
            for i in m.find():
                _ = {}
                _['hl'] = i['hl']
                _['day'] = i['day']
                _['time'] = i['time']
                list_data.append(_)
            list_data = sorted(list_data, key=lambda x: x['time'])
            request.websocket.send(json.dumps(list_data))
            time.sleep(60)


# 微信支付
def trans_xml_to_dict(data_xml):
    soup = BeautifulSoup(data_xml, features='xml')
    xml = soup.find('xml')  # 解析XML
    if not xml:
        return {}
    data_dict = dict([(item.name, item.text) for item in xml.find_all()])
    return data_dict


def trans_dict_to_xml(data_dict):  # 定义字典转XML的函数
    data_xml = []
    for k in sorted(data_dict.keys()):  # 遍历字典排序后的key
        v = data_dict.get(k)  # 取出字典中key对应的value
        if k == 'detail' and not v.startswith('<![CDATA['):  # 添加XML标记
            v = '<![CDATA[{}]]>'.format(v)
        data_xml.append('<{key}>{value}</{key}>'.format(key=k, value=v))
    return '<xml>{}</xml>'.format(''.join(data_xml))  # 返回XML


def get_sign(data_dict, key):  # 签名函数，参数为签名的数据和密钥
    params_list = sorted(data_dict.items(), key=lambda e: e[0], reverse=False)  # 参数字典倒排序为列表
    params_str = "&".join(u"{}={}".format(k, v) for k, v in params_list) + '&key=' + key
    # 组织参数字符串并在末尾添加商户交易密钥
    md5 = hashlib.md5()  # 使用MD5加密模式
    md5.update(params_str.encode())  # 将参数字符串传入
    sign = md5.hexdigest().upper()  # 完成加密并转为大写
    return sign


import snowflake.client

r = PyRedis(decode_responses=True)


class wx_pay(APIView):

    def get(self, request):
        uid = request.query_params.get('uid')
        money = request.query_params.get('money')
        money = float(money) * 100
        money = int(money)
        if int(uid) & 1 == 1:
            print(111)
            orderid = snowflake.client.get_guid()  # 雪花算法生成订单号
            print(orderid, '-----1---------')
        else:
            print(222)
            host = '127.0.0.1'
            port = 8920
            snowflake.client.setup(host, port)
            orderid = snowflake.client.get_guid()
            print(orderid, '------2--------')
        url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'  # 微信扫码支付接口
        key = '945bec9df3614cffb74e39aba8fbf7d7'  # 商户api秘钥
        total_fee = money  # 支付金额，单位分

        body = 'jiao qian'  # 商品描述
        params = {
            'appid': 'wx092344a76b9979ff',  # APPID
            'mch_id': '1602932608',  # 商户号
            'notify_url': 'http://wxpay.v3u.cn/wx_back/',  # 支付域名回调地址
            'product_id': 'goods_%s' % random.randrange(100000, 999999),  # 商品编号
            'trade_type': 'NATIVE',  # 支付类型（扫码支付）
            'spbill_create_ip': '114.254.176.137',  # 发送请求服务器的IP地址
            'total_fee': total_fee,  # 订单总金额
            'out_trade_no': orderid,  # 订单编号
            'body': body,  # 商品描述
            'nonce_str': 'ibuaiVcKdpRxkhJA'  # 字符串
        }
        sign = get_sign(params, key)  # 获取签名
        params.setdefault('sign', sign)  # 添加签名到参数字典
        xml = trans_dict_to_xml(params)  # 转换字典为XML
        response = requests.request('post', url, data=xml)  # 以POST方式向微信公众平台服务器发起请求
        data_dict = trans_xml_to_dict(response.content)  # 将请求返回的数据转为字典
        qrcode_name = 'erweima' + '.png'  # 支付二维码图片保存路径
        if data_dict.get('return_code') == 'SUCCESS':  # 如果请求成功
            img = qrcode.make(data_dict.get('code_url'))  # 创建支付二维码片
            img.save('./media/' + qrcode_name)  # 保存支付二维码
        print(orderid, '-----------shuchu---------')
        return Response({"img": qrcode_name, 'orderid': str(orderid)})

    def post(self, request):
        # 统一订单查询接口
        orderid = request.data.get('orderid')
        uid = request.data.get('uid')
        url = "https://api.mch.weixin.qq.com/pay/orderquery"

        key = '945bec9df3614cffb74e39aba8fbf7d7'  # 商户api密钥

        params = {
            'appid': 'wx092344a76b9979ff',  # APPID
            'mch_id': '1602932608',  # 商户号
            'out_trade_no': orderid,  # 订单编号
            'nonce_str': 'ibuaiVcKdpRxkhJA'  # 随机字符串
        }
        sign = get_sign(params, key)  # 获取签名
        params.setdefault('sign', sign)  # 添加签名到参数字典
        xml = trans_dict_to_xml(params)  # 转换字典为XML
        response = requests.request('post', url, data=xml)  # 以POST方式向微信公众平台服务器发起请求
        data_dict = trans_xml_to_dict(response.content)  # 将请求返回的数据转为字典
        print(data_dict)
        if data_dict['trade_state_desc'] == '支付成功':
            date_time = data_dict['time_end']
            unit = data_dict['fee_type']
            money = data_dict['total_fee']
            money = float(money) / 100
            ft = bin(int(orderid))[-17:-12]
            ft = int(ft, 2)
            r.push(f'rmborder{ft}',
                   str({'uid': uid, 'orderid': orderid, 'money': '+' + str(money), 'unit': unit, 'time': date_time}))
            key = f'{uid}_cje'  # 人民币钱包金额
            sum = r.get(key)
            if sum:
                sum = float(sum) + float(money)
                r.set(key, sum)
            else:
                r.set(key, money)
            return HttpResponse('ok')
        else:
            return HttpResponse('no')

    def put(self, request):
        uid = request.query_params.get('uid')
        print(uid)
        key = f'{uid}_cje'  # 人民币钱包金额
        money = r.get(key)
        if not money:
            money = '0'
        return Response(money)


class RmbOrder(APIView):
    def get(self, request):
        uid = request.query_params.get('uid')
        page = request.query_params.get('page')
        size = 1
        start = (int(page) - 1) * size
        end = int(page) * size
        if int(uid) & 1 == 1:
            key1 = 'rmborder2'
            data1 = r.lrange(key1)
            list1 = []
            for i in data1:
                i = eval(i)
                _ = {}
                print(i)
                if i['uid'] == uid:
                    _['uid'] = i['uid']
                    _['orderid'] = i['orderid']
                    _['money'] = i['money']
                    _['unit'] = i['unit']
                    _['time'] = i['time']
                    list1.append(_)
            list1 = sorted(list1, key=lambda x: x['time'])
            return Response({"data": list1[start:end], 'total': len(list1[start:end])})
        else:
            key2 = 'rmborder1'
            data2 = r.lrange(key2)
            list2 = []
            for j in data2:
                j = eval(j)
                _ = {}
                if j['uid'] == uid:
                    _['uid'] = j['uid']
                    _['orderid'] = j['orderid']
                    _['money'] = j['money']
                    _['unit'] = j['unit']
                    _['time'] = j['time']
                list2.append(_)
            list2 = sorted(list2, key=lambda x: x['time'])
        return Response({"data": list2[start:end], 'total': len(list2[start:end])})

    def post(self, request):
        orderid = request.data.get('orderid')
        ft = bin(int(orderid))[-17:-12]
        ft = int(ft, 2)
        key = f'rmborder{ft}'
        data = r.lrange(key)
        list1 = []
        for i in data:
            i = eval(i)
            _ = {}
            print(orderid)
            if i['orderid'] == orderid:
                _['uid'] = i['uid']
                _['orderid'] = i['orderid']
                _['money'] = i['money']
                _['unit'] = i['unit']
                _['time'] = i['time']
                list1.append(_)
        return Response(list1)


import paypalrestsdk


# 美金支付流程
def payment(request):
    uid = request.GET.get('uid')
    client_id = 'AQsWd93tA4bLaIZolLPy_6Inqc4QxzKhh4_tlxZKzO0HqiwZVdKlgI1mJgqA41jWev60lT-Q9poa9TGi'
    client_secret = 'EOIjbHatEH4J_sG6axTutfvC3f0kS3xSkuZuwr1A2Bds1C0t7XOqICKfHdQyeJl9XaRSXr3RrBb3nOTS'
    paypalrestsdk.configure({
        "mode": "sandbox",
        "client_id": client_id,
        "client_secret": client_secret})

    payment = paypalrestsdk.Payment({
        "intent": "sale",
        "payer": {
            "payment_method": "paypal"},
        "redirect_urls": {
            "return_url": "http://localhost:8000/userapp/payment_execute/?uid=" + uid,  # 支付成功跳转页面
            "cancel_url": "http://localhost:3000/paypal/cancel/"},  # 取消支付页面
        "transactions": [{
            "amount": {
                "total": "8.00",
                "currency": "USD"},
            "description": "这是一个订单测试"}]})
    if payment.create():
        for link in payment.links:
            if link.rel == "approval_url":
                approval_url = str(link.href)
                return HttpResponse(approval_url)
    else:
        print(payment.error)
        return HttpResponse("支付失败")


# 美金回调地址
def payment_execute(request):
    paymentid = request.GET.get("paymentId")  # 订单id
    payerid = request.GET.get("PayerID")  # 支付者id
    uid = request.GET.get('uid')
    payment = paypalrestsdk.Payment.find(paymentid)
    print(uid, '---------------uid----------')
    if payment.execute({"payer_id": payerid}):
        data = payment['transactions'][0]['amount']
        money = data['total']  # 金额
        unit = data['currency']  # 单位
        date_time = datetime.utcnow()  # utc当前时间
        print(date_time)
        r.push('mjorder',
               str({'uid': uid, 'orderid': paymentid, 'money': '+' + money, 'unit': unit, 'time': date_time}))
        key = f'{uid}_nje'  # 美金钱包金额
        sum = r.get(key)
        if sum:
            sum = float(sum) + float(money)
            r.set(key, sum)
        else:
            r.set(key, money)
        return redirect('http://127.0.0.1:8080/#/index')
    else:
        print(payment.error)
        return HttpResponse("支付失败")


class mj(APIView):
    def get(self, request):
        uid = request.query_params.get('uid')
        key = f'{uid}_nje'  # 美金钱包金额
        money = r.get(key)
        if not money:
            money = '0'
        return Response(money)


# 排行榜
class Order(APIView):
    def get(self, request):
        user = UserModel.objects.all()
        key = 'order'
        [r.zadd(key, {i.username: i.num}) for i in user]
        list1 = r.zrange(key)
        list1 = sorted(list1, key=lambda x: x[1], reverse=True)
        return Response(list1)
